package com.guochu.utils;

import cn.hutool.core.util.StrUtil;
import com.guochu.sys.entity.Annex;
import com.guochu.sys.service.AnnexService;
import org.apache.commons.collections.map.HashedMap;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: weibenquan
 * @Date: 2019-10-10 10:52
 */
@Component
public class FastDFSUtil {
    private static AnnexService annexService;

    @Autowired
    public void setTodaynotaryService(AnnexService annexService) {
        FastDFSUtil.annexService = annexService;
    }

    /**
     * 将 MultipartFile 转换成 二进制数组 调用上传文件服务器工具类
     * 返回 Annex
     *
     * @param files
     * @return
     */
    public static Annex uploadFastdfs(MultipartFile files, String groupId) {
        Annex annex = new Annex();
        annex.setId(UUID.randomUUID().toString());//ID
        String fileName = files.getOriginalFilename();
        annex.setFileName(fileName);//文件名
        annex.setFileType(fileName.substring(fileName.lastIndexOf(".") + 1));//文件后缀
        annex.setFileSize(files.getSize() / 1024);//文件大小
        annex.setGroupId(groupId);// 分组ID
        byte[] bytes = null;
        try {
            bytes = files.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath = "https://gjwy.nephil.cn:45/" + uploadFile(bytes, annex.getFileType());
        // 赋值上传服务器返回路径
        annex.setFilePath(filePath);//文件路径
        annexService.insert(annex);
        return annex;
    }

    public static String uploadFastdfsImg(MultipartFile files) {
        String fileName = files.getOriginalFilename();
        byte[] bytes = null;
        try {
            bytes = files.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath = "http://8.155.28.7:45/" + uploadFile(bytes, fileName.substring(fileName.lastIndexOf(".") + 1));
        return filePath;
    }


    public static Map<String, Object> uploadVideo(MultipartFile files) throws FrameGrabber.Exception {
        Map<String, Object> limit = new HashMap<String, Object>();
        String fileName = files.getOriginalFilename();
        byte[] bytes = null;
        try {
            bytes = files.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String filePath = "http://8.155.28.7:45/" + uploadFile(bytes, fileName.substring(fileName.lastIndexOf(".") + 1));
        limit.put("videoUrl", filePath);
        FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
        ff.start();
        Frame f;
        int lenght = ff.getLengthInFrames();
        int i = 0;
        String path = null;
        while (i < lenght) {
            // 过滤前5帧，避免出现全黑的图片，依自己情况而定
            f = ff.grabFrame();
            if ((i > 200) && (f.image != null)) {
                if (null == f || null == f.image) {
                    System.out.println("失败");
                }
                Java2DFrameConverter converter = new Java2DFrameConverter();
                BufferedImage bi = converter.getBufferedImage(f);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                try {
                    ImageIO.write(bi, "jpg", baos);
                    byte[] bytes1 = baos.toByteArray();
                    String filePath1 = "http://8.155.28.7:45/" + uploadFile(bytes1, "jpg");
                    limit.put("videoImage", filePath1);
                } catch (IOException e) {
                    System.out.println("缩略图写入文件夹失败");
                }
                break;
            }
            i++;
        }
        ff.stop();
        return limit;
    }

    /**
     * 将二进制数组上传到FastDFS服务器
     *
     * @param byteFile
     * @param ext_file
     * @return
     */
    public static String uploadFile(byte[] byteFile, String ext_file) {

        // 拼接服务区的文件路径
        StringBuffer sbPath = new StringBuffer();
        try {
            // 初始化文件资源
            ClientGlobal.initByProperties("fastDFS.properties");
            // 链接FastDFS服务器，创建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getConnection();
            String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
            StorageServer storageServer = getStorageServer(storageServerIp);
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            //利用字节流上传文件
            String[] strings = storageClient.upload_file(byteFile, ext_file, null);
            sbPath.append(StrUtil.join("/", strings));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
        return sbPath.toString();
    }

    /**
     * 得到Storage服务
     *
     * @param storageIp
     * @return 返回Storage服务
     */
    public static StorageServer getStorageServer(String storageIp) {
        StorageServer storageServer = null;
        if (storageIp != null && !("").equals(storageIp)) {
            try {
                // ip port store_path下标
                storageServer = new StorageServer(storageIp, 23000, 0);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return storageServer;
    }

    /**
     * 获得可用的storage IP
     *
     * @param trackerClient
     * @param trackerServer
     * @return 返回storage IP
     */
    public static String getStorageServerIp(TrackerClient trackerClient, TrackerServer trackerServer) {
        String storageIp = null;
        if (trackerClient != null && trackerServer != null) {
            try {
                StorageServer storageServer = trackerClient.getStoreStorage(trackerServer, "group1");
                storageIp = storageServer.getSocket().getInetAddress().getHostAddress();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return storageIp;
    }
}
